#pragma once

#include <sstream>
#include "zakengine/zak.h"

using namespace zak;

#include "basestate.h"
#include "peon.h"
#include "level.h"

class Peon;

//------------------------------------------------------------------------
// IdleState: 
// - Peon stands in an idle State.
// - If Peon capacity is at full switch to DepositState
// - If Peon capacity is not at full switch to MineState
//------------------------------------------------------------------------
class IdleState : public BaseState<Peon>
{
private:

	// Class Constructor
	IdleState(){}

	// Copy ctor and assignment should be private
	IdleState(const IdleState&);
	IdleState& operator=(const IdleState&);

public:

	// This is a singleton
	static IdleState* Instance();

	virtual void Enter(Peon* pPeon);

	virtual void Execute(Peon* pPeon);

	virtual void Exit(Peon* pPeon);

	virtual bool OnMessage(Peon* pPeon, const Telegram& message);
};

//------------------------------------------------------------------------
// MineState: 
// - If not at the mine, peon walks to the mine. 
// - If already at the mine, he starts digging.
// - If his capacity is at full he switches to DepositState.
//------------------------------------------------------------------------
class MineState : public BaseState<Peon>
{
private:

	// Class Constructor
	MineState(){}

	// Copy ctor and assignment should be private
	MineState(const MineState&);
	MineState& operator=(const MineState&);

public:

	// This is a singleton
	static MineState* Instance();

	virtual void Enter(Peon* pPeon);

	virtual void Execute(Peon* pPeon);

	virtual void Exit(Peon* pPeon);

	virtual bool OnMessage(Peon* pPeon, const Telegram& message);
};


//------------------------------------------------------------------------
// DepositState: 
// - Walks to the town to deposit gold.
// - If his capacity is at empty he switches to MineState
//------------------------------------------------------------------------
class DepositState : public BaseState<Peon>
{
private:

	// Class Constructor
	DepositState(){}

	// Copy ctor and assignment should be private
	DepositState(const DepositState&);
	DepositState& operator=(const DepositState&);

public:

	// This is a singleton
	static DepositState* Instance();

	virtual void Enter(Peon* pPeon);

	virtual void Execute(Peon* pPeon);

	virtual void Exit(Peon* pPeon);

	virtual bool OnMessage(Peon* pPeon, const Telegram& message);
};

//------------------------------------------------------------------------
// WalkState: 
// - Walks to the town to deposit gold if bags are full
// - Walks to mine if bag is empty
//------------------------------------------------------------------------
class WalkState : public BaseState<Peon>
{
private:

	// Class Constructor
	WalkState(){}

	// Copy ctor and assignment should be private
	WalkState(const WalkState&);
	WalkState& operator=(const WalkState&);

public:

	// This is a singleton
	static WalkState* Instance();

	virtual void Enter(Peon* pPeon);

	virtual void Execute(Peon* pPeon);

	virtual void Exit(Peon* pPeon);

	virtual bool OnMessage(Peon* pPeon, const Telegram& message);
};

//------------------------------------------------------------------------
// PeonGlobalState: 
//------------------------------------------------------------------------
class PeonGlobalState : public BaseState<Peon>
{
private:

	// Class Constructor
	PeonGlobalState(){}

	// Copy ctor and assignment should be private
	PeonGlobalState(const DepositState&);
	PeonGlobalState& operator=(const DepositState&);

public:

	// This is a singleton
	static PeonGlobalState* Instance();

	virtual void Enter(Peon* pPeon);

	virtual void Execute(Peon* pPeon);

	virtual void Exit(Peon* pPeon);

	virtual bool OnMessage(Peon* pPeon, const Telegram& message);
};